#include "testinterface.h"
#include "ui_testinterface.h"
#include <QFileDialog>
#include <QVariant>
#include <QDateTime>

#include "Freya_Define.h"
#include "dataoperate.h"
#include "commessage.h"
#include "systemlog.h"

#define MAXLOGLENTH 2000

TestInterface::TestInterface(QWidget *parent) :
    QWidget(parent), FreyaBaseAction(FreyaBaseControl::GetFreyaControl(), "FreyaVerification", false),
    ui(new Ui::TestInterface)
{
    ui->setupUi(this);

    ComMessage nComMessage;
    ui->cbx_parameter->addItem("ComMessage", nComMessage.ToVariant());

    DataOperate nDataOperate;
    ui->cbx_parameter->addItem("DataOperate", nDataOperate.ToVariant());

    SystemLog nSystemLog;
    ui->cbx_parameter->addItem("SystemLog", nSystemLog.ToVariant());

    m_timer = new QTimer(this);
    connect(m_timer, SIGNAL(timeout()), this, SLOT(onDoprocessTimer()));

    QString label_version = "Ver：" + (QString)FREYAMODULE_VER;
    ui->label_Version->setText(label_version);
    ui->label_This->setText("this:" + QString::asprintf("%p", this));
}

TestInterface::~TestInterface()
{
    delete ui;
}

void TestInterface::on_btn_readfile_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("Load command define"), "./" , "text(*.h)");
    QFile file(fileName);

    if (!file.open(QFile::ReadOnly | QFile::Text))
    {
        qWarning() << "Cannot open define file!";
        return;
    }

    QTextStream txt(&file);
    while(!txt.atEnd())
    {
        QString cmdLine = txt.readLine().remove(" ");
        if(cmdLine.startsWith("#defineRFG_CMD_"))
        {
            QStringList Target_text = cmdLine.split("x", QString::SkipEmptyParts);
            QStringList Target_text2 = Target_text.at(1).split("U");
            if(Target_text2.size() > 1)
            {
                QString noteLine = txt.readLine().remove(" ");
                ui->cbx_command->addItem("0x" + Target_text2.at(0) + noteLine.toLocal8Bit());
            }
        }
    }
    file.close();
}

void TestInterface::on_cbx_parameter_currentIndexChanged(const QString &/*arg1*/)
{
    foreach(QObject *obj, m_ItemList)
    {
        obj->deleteLater();
    }
    m_ItemList.clear();
    m_ValueMap.clear();

    qDebug() << ui->cbx_parameter->currentData().toMap();

    QMap<QString, QVariant > parameterMap = ui->cbx_parameter->currentData().toMap();
    QMapIterator<QString, QVariant > paramIt(parameterMap);
    while (paramIt.hasNext())
    {
        paramIt.next();

        QHBoxLayout *pHLay = new QHBoxLayout;
        QLineEdit *keyLEdit = new QLineEdit;
        QComboBox *typeCbox = new QComboBox;
        QLineEdit *ValueLEdit = new QLineEdit;

        pHLay->addWidget(keyLEdit);
        pHLay->addWidget(typeCbox);
        pHLay->addWidget(ValueLEdit);

        pHLay->setStretchFactor(keyLEdit,4);
        pHLay->setStretchFactor(typeCbox,3);
        pHLay->setStretchFactor(ValueLEdit,3);
        m_ItemList.append(pHLay);
        m_ItemList.append(keyLEdit);
        m_ItemList.append(typeCbox);
        m_ItemList.append(ValueLEdit);
        ui->prarmVLay->addLayout(pHLay);

        m_ValueMap.insert(paramIt.key(), ValueLEdit);

        keyLEdit->setText(paramIt.key());

        QVariant val = paramIt.value();
        QString valtostr;
        switch (val.type())
        {
        case QVariant::Bool:
            typeCbox->addItem("bool");
            valtostr = val.toString();
            break;
        case QVariant::Int:
            typeCbox->addItem("int");
            valtostr = val.toString();
            break;
        case QVariant::String:
            typeCbox->addItem("string");
            valtostr = val.toString();
            break;
        case QVariant::Double:
            typeCbox->addItem("double");
            valtostr = val.toString();
            break;
        case QVariant::StringList:
            typeCbox->addItem("stringlist");
            valtostr = val.toStringList().join(";");
            break;
        default:
            break;
        }
        ValueLEdit->setText(valtostr);
    }
}

void TestInterface::on_StartBtn_clicked()
{
    if(m_timer->isActive() == false)
    {
        m_timer->start(ui->lineEdit->text().toInt());
        onDoprocessTimer();
    }
}

void TestInterface::onDoprocessTimer()
{
    QString str_command = this->ui->cbx_command->currentText();
    quint64 cmd1 = str_command.split("//").at(0).toLongLong(nullptr, 0);
    FreyaData data = FreyaBaseData::CreateData(cmd1);

    static int f = 0;
    data->dataID = QString::number(++f);

    QVariantMap varMap = ui->cbx_parameter->currentData().toMap();
    QVariantMap sendMap;
    QMapIterator<QString, QVariant> varIt(varMap);
    while(varIt.hasNext())
    {
        varIt.next();

        m_ValueMap.value(varIt.key());

        switch(varIt.value().type())
        {
        case QVariant::StringList:
            sendMap.insert(varIt.key(), m_ValueMap.value(varIt.key())->text().split(";"));
            break;
        case QVariant::Int:
            sendMap.insert(varIt.key(), m_ValueMap.value(varIt.key())->text().toInt(nullptr, 0));
            break;
        case QVariant::Double:
            sendMap.insert(varIt.key(), m_ValueMap.value(varIt.key())->text().toDouble());
            break;
        case QVariant::String:
            sendMap.insert(varIt.key(), m_ValueMap.value(varIt.key())->text());
            break;
        case QVariant::Bool:
            sendMap.insert(varIt.key(), m_ValueMap.value(varIt.key())->text() == "true");
            break;
        default:
            break;
        }
    }

    data->SetArgument(sendMap);
    FREYA_REQUESTEXECUTION(data);

    static int i = 1;

    QString timerString = "###################################Times:" + QString::number(i);
    ui->textEdit->append(timerString);
    qDebug() << timerString;

    if(++i > ui->timesLEdit->text().toInt())
    {
        i = 1;
        m_timer->stop();
    }

    QString &&logContent = ui->textEdit->toPlainText();

    if(logContent.length() > MAXLOGLENTH)
    {
        ui->textEdit->setPlainText(logContent.right(MAXLOGLENTH));
        ui->textEdit->moveCursor(QTextCursor::End);
    }
}

void TestInterface::on_btn_clear_clicked()
{
    ui->textEdit->clear();
}

void TestInterface::Execute(const FreyaData data)
{
    ui->textEdit->append("CMD:0x" + QString::number(data->command, 16));

    QString actName;
//    FreyaBaseAction *objAct = static_cast<FreyaBaseAction*>(m_FreyaBaseControl->FreyaRequester(data));
//    if(objAct)
//    {
//        actName = objAct->ActionName();
//    }

    ui->textEdit->append("SRC:" + actName + "(" + QString::asprintf("%p", m_FreyaBaseControl->FreyaRequester(data)) + ")");
    ui->textEdit->append("TIM:" + QDateTime::currentDateTime().toString(Qt::SystemLocaleLongDate));
    ui->textEdit->append("ARG:");

    QVariantMap map1 = data->GetArgument().toMap();
    QStringList listKey = map1.keys();

    foreach(const QString &str, listKey)
    {
        QString text = "    " + str;
        QVariant var = map1.value(str);

        switch (var.type())
        {
        case QVariant::Int:
            text.append("=Int:");
            text.append(QString::number(var.toInt()));
            break;
        case QVariant::String:
            text.append("=String:");
            text.append(var.toString());
            break;
        case QVariant::Double:
            text.append("=Double:");
            text.append(QString::number(var.toDouble()));
            break;
        case QVariant::Bool:
            text.append("=Bool:");
            text.append(var.toString());
            break;
        case QVariant::StringList:
            text.append("=StringList:");
            text.append(var.toStringList().join(";"));
            break;
        default:
            break;
        }
        ui->textEdit->append(text);
    }

    ui->textEdit->append("======================================");
}
